<template>
  <div id="map" ref="rootmap">
  </div>
</template>

<script>
import { data as weibo } from '@/assets/weibo-gl'
import { Feature, Map, View } from 'ol'
import ol3Echarts from 'ol-echarts'
import { LineString, Point } from 'ol/geom'
import { Vector as LayerVector } from 'ol/layer'
import TileLayer from 'ol/layer/Tile'
import WebGLPointsLayer from 'ol/layer/WebGLPoints'
import 'ol/ol.css'
import { Cluster, TileImage, Vector as SourceVector, XYZ } from 'ol/source'
import OSM from 'ol/source/OSM'
import { Circle, Fill, Stroke, Style, Text } from 'ol/style'
import TileGrid from 'ol/tilegrid/TileGrid'

export default {
  name: 'HelloWorld',
  data() {
    return {
      map: undefined,
      newStyle: {
        symbol: {
          symbolType: 'circle',
          size: [
            'interpolate',
            ['linear'],
            ['get', 'population'],
            40000,
            5,
            2000000,
            8],
          color: [
            'interpolate',
            ['linear'],
            ['get', 'latitude'],
            -80,
            '#ff14c3',
            -20,
            '#ff621d',
            20,
            '#ffed02',
            80,
            '#00ff67'],
          offset: [0, 0],
          opacity: 0.95,
        },
      },
      pointsLayer: undefined
    }
  },
  mounted() {
    let mapContainer = this.$refs.rootmap
    let resolutions = [];
    for (let i = 0; i < 19; i++) {
      resolutions[i] = Math.pow(2, 18 - i);
    }
    let tilegrid = new TileGrid({
      origin: [0, 0],
      resolutions: resolutions
    })
    let baidu_source = new TileImage({
      projection: "EPSG:3857",
      tileGrid: tilegrid,
      tileUrlFunction: function (tileCoord) {
        if (!tileCoord) return "";
        let z = tileCoord[0];
        let x = tileCoord[1];
        let y = -tileCoord[2];

        if (x < 0) {
          x = "M" + -x;
        }
        if (y < 0) {
          y = "M" + -y;
        }
        return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20151021&scaler=1&p=1";
      }
    });
    //百度源
    let baidu_layer = new TileLayer({
      source: baidu_source
    });
    //彩色中国源
    let color_layer = new TileLayer({
      source: new XYZ({
        url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}'
      })
    })
    //原版源
    let orgin_layer = new TileLayer({
      source: new OSM(),
    })
    this.map = new Map({
      target: "map",
      layers: [

        // new TileLayer({
        //   source: new OSM(),
        // }),

        baidu_layer
        // color_layer
        // orgin_layer
      ],
      view: new View({
        projection: "EPSG:4326",    //使用这个坐标系
        center: [114.064839, 22.548857],  //深圳
        zoom: 12
      })
    })
    setTimeout(() => {
      // this.vectorTileLayer()
      // this.massiveFeature()
      // this.webGLPointsLayer()
      // this.animate()
      // this.echartsLayer()
      // this.drawLine()
      // this.runLine()
    }, 100)
  },
  methods: {
    //添加单个点位
    vectorTileLayer() {
      let vectorSource = new SourceVector({})
      let feature = new Feature({
        geometry: new Point([114.064839111, 22.5488572222], 'XY')
      })
      vectorSource.addFeature(feature)
      let iconStyle = new Style({
        image: new Circle({
          radius: 10,
          stroke: new Stroke({
            color: '#fff'
          }),
          fill: new Fill({
            color: '#3399CC'
          })
        })
      })
      let layerVector = new LayerVector({
        source: vectorSource,
        style: iconStyle
      })
      this.map.addLayer(layerVector)
    },
    //添加聚合图层
    //10W个点位卡死 浏览器崩溃
    massiveFeature() {
      let lnglats = new Array(5000).fill(0).map((item, index) => {
        return [114.963 + 0.000001 * index, 22.623 + 0.000001 * index]
      })
      let features = lnglats.map(item => new Feature({
        geometry: new Point(item, 'XY')
      }))
      let source = new SourceVector({
        features: features
      })
      let cluster = new Cluster({
        distance: 40,
        source: source
      })
      var styleCache = {};
      let clusterVector = new LayerVector({
        source: cluster,
        style: (feature, resolution) => {
          let size = feature.get('features').length
          let style = styleCache[size]
          if (!style) {
            style = [
              new Style({
                image: new Circle({
                  radius: 10,
                  stroke: new Stroke({
                    color: '#fff'
                  }),
                  fill: new Fill({
                    color: '#3399CC'
                  })
                }),
                text: new Text({
                  text: size.toString(),
                  fill: new Fill({
                    color: '#fff'
                  })
                })
              })
            ]
            styleCache[size] = style
          }
          return style
        }
      })
      this.map.addLayer(clusterVector)
    },
    // 海量点
    // 10W
    webGLPointsLayer() {
      let lnglats = new Array(100000).fill(0).map((item, index) => {
        return [114.963 + 0.000001 * index, 22.623 + 0.000001 * index]
      })
      let features = lnglats.map(item => new Feature({
        geometry: new Point(item, 'XY')
      }))
      let source = new SourceVector({
        features: features
      })
      let previousLayer = this.pointsLayer;
      this.pointsLayer = new WebGLPointsLayer({
        source: source,
        style: this.newStyle,
        disableHitDetection: true,
      });
      this.map.addLayer(this.pointsLayer);
      if (previousLayer) {
        this.map.removeLayer(previousLayer);
        previousLayer.dispose();
      }
    },
    animate() {
      this.map.render();
      window.requestAnimationFrame(this.animate);
    },
    //与echarts结合 海量点
    //10W+ 内存少，但是还是很卡
    //echarts 版本<5.0
    echartsLayer() {
      var weiboData = weibo.map(function (serieData, idx) {
        var px = serieData[0] / 1000;
        var py = serieData[1] / 1000;
        var res = [[px, py]];
        for (var i = 2; i < serieData.length; i += 2) {
          var dx = serieData[i] / 1000;
          var dy = serieData[i + 1] / 1000;
          var x = px + dx;
          var y = py + dy;
          res.push([x.toFixed(2), y.toFixed(2), 1]);
          px = x;
          py = y;
        }
        return res;
      });
      var option = {
        title: {
          text: '微博签到数据点亮中国',
          left: 'center',
          top: 'top',
          textStyle: {
            color: '#fff'
          }
        },
        tooltip: {},
        legend: {
          left: 'right',
          data: ['强', '中', '弱'],
          textStyle: {
            color: '#ccc'
          }
        },
        series: [
          {
            name: '弱',
            type: 'scatter',
            symbolSize: 1,
            itemStyle: {
              shadowBlur: 2,
              shadowColor: 'rgba(37, 140, 249, 0.8)',
              color: 'rgba(37, 140, 249, 0.8)'
            },
            data: weiboData[0]
          },
          {
            name: '中',
            type: 'scatter',
            symbolSize: 1,
            itemStyle: {
              shadowBlur: 2,
              shadowColor: 'rgba(14, 241, 242, 0.8)',
              color: 'rgba(14, 241, 242, 0.8)'
            },
            data: weiboData[1]
          },
          {
            name: '强',
            type: 'scatter',
            symbolSize: 1,
            itemStyle: {
              shadowBlur: 2,
              shadowColor: 'rgba(255, 255, 255, 0.8)',
              color: 'rgba(255, 255, 255, 0.8)'
            },
            data: weiboData[2]
          }
        ]
      };
      let echartslayer = new ol3Echarts(option, {
        hideOnMoving: false,
        hideOnZooming: false,
        forcedPrecomposeRerender: true
      });
      echartslayer.appendTo(this.map)
    },
    // 画线
    drawLine() {
      let lnglat = [
        [114.064839111, 22.5488572222],
        [124.064839222, 23.5488572333],
        [134.064839333, 24.5488572444]
      ]
      let features = lnglat.map(item => {
        return new Feature({
          geometry: new Point(item, 'XY')
        })
      })
      let lineFeature = new Feature({
        geometry: new LineString(lnglat)
      })
      let source = new SourceVector({
        features: [...features, lineFeature]
      })
      let layer = new LayerVector({
        source: source
      })
      this.map.addLayer(layer)
    },
    //运行轨迹
    runLine() {
      let lnglat = [
        [114.064839111, 22.5488572222],
        [124.064839222, 23.5488572333],
        [134.064839333, 24.5488572444]
      ]
      // let features = lnglat.map(item => {
      //   return new Feature({
      //     geometry: new Point(item, 'XY')
      //   })
      // })
      let geometry = new LineString(lnglat)
      let lineFeature = new Feature(geometry)
      let source = new SourceVector({
        features: [lineFeature]
      })
      let layer = new LayerVector({
        source: source,
        style: new Style({
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          }),
          stroke: new Stroke({
            color: '#f00',
            width: 4
          }),
          image: new Circle({
            radius: 2,
            fill: new Fill({
              color: '#f00'
            })
          })
        })
      })
      this.map.addLayer(layer)
      console.log('开始画图')
      let lngX = lnglat[2][0];
      let lngY = lnglat[2][1];
      let count = 0;
      let interval = setInterval(function () {
        console.log(count++)
        lngX = lngX - Math.random() * 30;
        lngY = lngY + Math.random() * 30;
        let newPoint = [lngX, lngY];
        // lnglat.shift();
        lnglat.push(newPoint);
        geometry.setCoordinates(lnglat);
      }, 300);

      setTimeout(function () {
        clearInterval(interval);
      }, 5000 * 10);
    },

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#map {
  height: 100%;
}

/*隐藏ol的一些自带元素*/
/deep/ .ol-attribution,
.ol-zoom {
  display: none;
}
</style>
